package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaSeat;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

//SW_FC_003_019  温度控制TemperatureControl
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacTemperatureSetTest extends VhalUnitTestBase {

    private static final String TAG = "HvacTemperatureSetTest";
    private static float halValueRow1Left;
    private static float halValueRow1Right;

    private static int halArea;

    private static final int HVAC_TEMPERATURE_SET = VehiclePropertyIds.HVAC_TEMPERATURE_SET;

    private static final int SERVICE_ID_CLIMATE = 112;
    private static final int OP_ID_CLIMATE = 0xc8;
    private static final int LOCK_TIME = 200;

    private static final int AREA_LEFT = VehicleAreaSeat.SEAT_ROW_1_LEFT;
    private static final int AREA_RIGHT = VehicleAreaSeat.SEAT_ROW_1_RIGHT;


    final static Object lockRow1Left = new Object();
    final static Object lockRow1Right = new Object();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, HVAC_TEMPERATURE_SET, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig(true);
        delay();
    }

    @Test
    public void testHvacTemperatureLeftRudSetAvailable_01() {
        setConfig(true);
        delay();
        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_LEFT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_LEFT, 26);
        delay();

        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_RIGHT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 26);
        delay();

    }

    @Test
    public void testHvacTemperatureLeftRudSetAvailable_02() {
        setConfig(true);
        delay();
        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_LEFT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_LEFT, 15.5f);
        delay();

        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_RIGHT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 15.5f);
        delay();

    }

    @Test
    public void testHvacTemperatureLeftRudSetAvailable_03() {
        setConfig(true);
        delay();
        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_LEFT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_LEFT, 28.5f);
        delay();

        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_RIGHT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 28.5f);
        delay();

    }


    @Test
    public void testHvacTemperatureRightRudSetAvailable_04() {
        setConfig(false);
        delay();
        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_LEFT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_LEFT, 26);
        delay();

        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_RIGHT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 26);
        delay();

    }

    @Test
    public void testHvacTemperatureRightRudSetAvailable_05() {
        setConfig(false);
        delay();
        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_LEFT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_LEFT, 15.5f);
        delay();

        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_RIGHT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 15.5f);
        delay();

    }

    @Test
    public void testHvacTemperatureRightRudSetAvailable_06() {
        setConfig(false);
        delay();
        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_LEFT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_LEFT, 28.5f);
        delay();

        testHvacTemperatureSetAvailable(VehicleAreaSeat.SEAT_ROW_1_RIGHT, true);
        testHvacTemperatureSetSet(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 28.5f);
        delay();

    }

    private static CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                halArea = carPropertyValue.getAreaId();
                Log.d(TAG, "HVAC_TEMPERATURE_SET onChangeEvent value: propertyId ：" + carPropertyValue.getPropertyId()
                        + " propertyValue：" + carPropertyValue.getValue() + " status: " + carPropertyValue.getStatus()
                        + " area：" + carPropertyValue.getAreaId());
                if (halArea == VehicleAreaSeat.SEAT_ROW_1_LEFT) {
                    halValueRow1Left = (float) carPropertyValue.getValue();
                    synchronized (lockRow1Left) {
                        lockRow1Left.notify();
                    }
                } else if (halArea == VehicleAreaSeat.SEAT_ROW_1_RIGHT) {
                    halValueRow1Right = (float) carPropertyValue.getValue();
                    synchronized (lockRow1Right) {
                        lockRow1Right.notify();
                    }
                } 
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {

        }
    };


    public void lockWait(int area) {
        try {
            if (area == VehicleAreaSeat.SEAT_ROW_1_LEFT) {
                synchronized (lockRow1Left) {
                    lockRow1Left.wait(LOCK_TIME);
                }
            } else if (area == VehicleAreaSeat.SEAT_ROW_1_RIGHT) {
                synchronized (lockRow1Right) {
                    lockRow1Right.wait(LOCK_TIME);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public void testHvacTemperatureSetAvailable(int area, boolean avail) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(HVAC_TEMPERATURE_SET, area);
        Log.d(TAG, "testHvacTemperatureSetAvailable isAvail：" + isAvail);
        Assert.assertEquals(avail,isAvail);
    }

    public void testHvacTemperatureSetSet(int area, float value) {
        Log.d(TAG, "testHvacTemperatureSetSet area：" + area + " value: " + value);
        mCarPropertyMgr.setFloatProperty(HVAC_TEMPERATURE_SET, area, value);
        lockWait(area);
        if (area == VehicleAreaSeat.SEAT_ROW_1_LEFT) {
            Assert.assertEquals(value, halValueRow1Left, 0);
        } else if (area == VehicleAreaSeat.SEAT_ROW_1_RIGHT) {
            Assert.assertEquals(value, halValueRow1Right, 0);
        }
    }

    public void testHvacTemperatureSetGet(int area, float value) {
        Log.d(TAG, "testHvacTemperatureSetGet area：" + area + " value: " + value);
        mCarPropertyMgr.setFloatProperty(HVAC_TEMPERATURE_SET, area, value);
        lockWait(area);
        float hvacTemperature = mCarPropertyMgr.getFloatProperty(HVAC_TEMPERATURE_SET, area);
        Assert.assertEquals(value, hvacTemperature, 0);
    }

    private static void setConfig(boolean isLeftRud) {
        IpcpClient ipcpClient = new IpcpClient();
        int ccSvcId = 135;
        int[] ccOperIds = {200};

        int cemSvcId = 37;
        int[] cemOperIds = {999};

        int srsSvcId = 43;
        int[] srsOperIds = {999};

        ipcpClient.setConfig(ccSvcId, ccOperIds);
        ipcpClient.setConfig(cemSvcId, cemOperIds);
        ipcpClient.setConfig(srsSvcId, srsOperIds);

        int[] ccConfigs = {8};
        int[] ccValues = {isLeftRud ? 1 : 2};
        boolean ccRet = ipcpClient.setCarconfigSignal(ccSvcId, ccOperIds[0], ccConfigs, ccValues);
        Assert.assertTrue(ccRet);
    }

}
